home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Vector.java < prev    next >
Text File  |  1998-09-22  |  18KB  |  558 lines

  1. /*
  2.  * @(#)Vector.java    1.39 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.util;
  16.  
  17. /**
  18.  * The <code>Vector</code> class implements a growable array of 
  19.  * objects. Like an array, it contains components that can be 
  20.  * accessed using an integer index. However, the size of a 
  21.  * <code>Vector</code> can grow or shrink as needed to accommodate 
  22.  * adding and removing items after the <code>Vector</code> has been created.
  23.  * <p>
  24.  * Each vector tries to optimize storage management by maintaining a 
  25.  * <code>capacity</code> and a <code>capacityIncrement</code>. The 
  26.  * <code>capacity</code> is always at least as large as the vector 
  27.  * size; it is usually larger because as components are added to the 
  28.  * vector, the vector's storage increases in chunks the size of 
  29.  * <code>capacityIncrement</code>. An application can increase the 
  30.  * capacity of a vector before inserting a large number of 
  31.  * components; this reduces the amount of incremental reallocation. 
  32.  *
  33.  * @author  Lee Boynton
  34.  * @author  Jonathan Payne
  35.  * @version 1.39, 07/01/98
  36.  * @since   JDK1.0
  37.  */
  38. public
  39. class Vector implements Cloneable, java.io.Serializable {
  40.     /**
  41.      * The array buffer into which the components of the vector are 
  42.      * stored. The capacity of the vector is the length of this array buffer.
  43.      *
  44.      * @since   JDK1.0
  45.      */
  46.     protected Object elementData[];
  47.  
  48.     /**
  49.      * The number of valid components in the vector. 
  50.      *
  51.      * @since   JDK1.0
  52.      */
  53.     protected int elementCount;
  54.  
  55.     /**
  56.      * The amount by which the capacity of the vector is automatically 
  57.      * incremented when its size becomes greater than its capacity. If 
  58.      * the capacity increment is <code>0</code>, the capacity of the 
  59.      * vector is doubled each time it needs to grow. 
  60.      *
  61.      * @since   JDK1.0
  62.      */
  63.     protected int capacityIncrement;
  64.  
  65.     /** use serialVersionUID from JDK 1.0.2 for interoperability */
  66.     private static final long serialVersionUID = -2767605614048989439L;
  67.  
  68.     /**
  69.      * Constructs an empty vector with the specified initial capacity and
  70.      * capacity increment. 
  71.      *
  72.      * @param   initialCapacity     the initial capacity of the vector.
  73.      * @param   capacityIncrement   the amount by which the capacity is
  74.      *                              increased when the vector overflows.
  75.      * @since   JDK1.0
  76.      */
  77.     public Vector(int initialCapacity, int capacityIncrement) {
  78.     super();
  79.     this.elementData = new Object[initialCapacity];
  80.     this.capacityIncrement = capacityIncrement;
  81.     }
  82.  
  83.     /**
  84.      * Constructs an empty vector with the specified initial capacity.
  85.      *
  86.      * @param   initialCapacity   the initial capacity of the vector.
  87.      * @since   JDK1.0
  88.      */
  89.     public Vector(int initialCapacity) {
  90.     this(initialCapacity, 0);
  91.     }
  92.  
  93.     /**
  94.      * Constructs an empty vector. 
  95.      *
  96.      * @since   JDK1.0
  97.      */
  98.     public Vector() {
  99.     this(10);
  100.     }
  101.  
  102.     /**
  103.      * Copies the components of this vector into the specified array. 
  104.      * The array must be big enough to hold all the objects in this  vector.
  105.      *
  106.      * @param   anArray   the array into which the components get copied.
  107.      * @since   JDK1.0
  108.      */
  109.     public final synchronized void copyInto(Object anArray[]) {
  110.     int i = elementCount;
  111.     while (i-- > 0) {
  112.         anArray[i] = elementData[i];
  113.     }
  114.     }
  115.  
  116.     /**
  117.      * Trims the capacity of this vector to be the vector's current 
  118.      * size. An application can use this operation to minimize the 
  119.      * storage of a vector. 
  120.      *
  121.      * @since   JDK1.0
  122.      */
  123.     public final synchronized void trimToSize() {
  124.     int oldCapacity = elementData.length;
  125.     if (elementCount < oldCapacity) {
  126.         Object oldData[] = elementData;
  127.         elementData = new Object[elementCount];
  128.         System.arraycopy(oldData, 0, elementData, 0, elementCount);
  129.     }
  130.     }
  131.  
  132.     /**
  133.      * Increases the capacity of this vector, if necessary, to ensure 
  134.      * that it can hold at least the number of components specified by 
  135.      * the minimum capacity argument. 
  136.      *
  137.      * @param   minCapacity   the desired minimum capacity.
  138.      * @since   JDK1.0
  139.      */
  140.     public final synchronized void ensureCapacity(int minCapacity) {
  141.     if (minCapacity > elementData.length) {
  142.         ensureCapacityHelper(minCapacity);
  143.     }
  144.     }
  145.  
  146.     /**
  147.      * This implements the unsynchronized semantics of ensureCapacity.
  148.      * Synchronized methods in this class can internally call this 
  149.      * method for ensuring capacity without incurring the cost of an 
  150.      * extra synchronization.
  151.      *
  152.      * @see java.util.Vector#ensureCapacity(int)
  153.      */ 
  154.     private void ensureCapacityHelper(int minCapacity) {
  155.     int oldCapacity = elementData.length;
  156.     Object oldData[] = elementData;
  157.     int newCapacity = (capacityIncrement > 0) ?
  158.         (oldCapacity + capacityIncrement) : (oldCapacity * 2);
  159.     if (newCapacity < minCapacity) {
  160.         newCapacity = minCapacity;
  161.     }
  162.     elementData = new Object[newCapacity];
  163.     System.arraycopy(oldData, 0, elementData, 0, elementCount);
  164.     }
  165.     
  166.     /**
  167.      * Sets the size of this vector. If the new size is greater than the 
  168.      * current size, new <code>null</code> items are added to the end of 
  169.      * the vector. If the new size is less than the current size, all 
  170.      * components at index <code>newSize</code> and greater are discarded.
  171.      *
  172.      * @param   newSize   the new size of this vector.
  173.      * @since   JDK1.0
  174.      */
  175.     public final synchronized void setSize(int newSize) {
  176.     if ((newSize > elementCount) && (newSize > elementData.length)) {
  177.         ensureCapacityHelper(newSize);
  178.     } else {
  179.         for (int i = newSize ; i < elementCount ; i++) {
  180.         elementData[i] = null;
  181.         }
  182.     }
  183.     elementCount = newSize;
  184.     }
  185.  
  186.     /**
  187.      * Returns the current capacity of this vector.
  188.      *
  189.      * @return  the current capacity of this vector.
  190.      * @since   JDK1.0
  191.      */
  192.     public final int capacity() {
  193.     return elementData.length;
  194.     }
  195.  
  196.     /**
  197.      * Returns the number of components in this vector.
  198.      *
  199.      * @return  the number of components in this vector.
  200.      * @since   JDK1.0
  201.      */
  202.     public final int size() {
  203.     return elementCount;
  204.     }
  205.  
  206.     /**
  207.      * Tests if this vector has no components.
  208.      *
  209.      * @return  <code>true</code> if this vector has no components;
  210.      *          <code>false</code> otherwise.
  211.      * @since   JDK1.0
  212.      */
  213.     public final boolean isEmpty() {
  214.     return elementCount == 0;
  215.     }
  216.  
  217.     /**
  218.      * Returns an enumeration of the components of this vector.
  219.      *
  220.      * @return  an enumeration of the components of this vector.
  221.      * @see     java.util.Enumeration
  222.      * @since   JDK1.0
  223.      */
  224.     public final synchronized Enumeration elements() {
  225.     return new VectorEnumerator(this);
  226.     }
  227.     
  228.     /**
  229.      * Tests if the specified object is a component in this vector.
  230.      *
  231.      * @param   elem   an object.
  232.      * @return  <code>true</code> if the specified object is a component in
  233.      *          this vector; <code>false</code> otherwise.
  234.      * @since   JDK1.0
  235.      */
  236.     public final boolean contains(Object elem) {
  237.     return indexOf(elem, 0) >= 0;
  238.     }
  239.  
  240.     /**
  241.      * Searches for the first occurence of the given argument, testing 
  242.      * for equality using the <code>equals</code> method. 
  243.      *
  244.      * @param   elem   an object.
  245.      * @return  the index of the first occurrence of the argument in this
  246.      *          vector; returns <code>-1</code> if the object is not found.
  247.      * @see     java.lang.Object#equals(java.lang.Object)
  248.      * @since   JDK1.0
  249.      */
  250.     public final int indexOf(Object elem) {
  251.     return indexOf(elem, 0);
  252.     }
  253.  
  254.     /**
  255.      * Searches for the first occurence of the given argument, beginning 
  256.      * the search at <code>index</code>, and testing for equality using 
  257.      * the <code>equals</code> method. 
  258.      *
  259.      * @param   elem    an object.
  260.      * @param   index   the index to start searching from.
  261.      * @return  the index of the first occurrence of the object argument in
  262.      *          this vector at position <code>index</code> or later in the
  263.      *          vector; returns <code>-1</code> if the object is not found.
  264.      * @see     java.lang.Object#equals(java.lang.Object)
  265.      * @since   JDK1.0
  266.      */
  267.     public final synchronized int indexOf(Object elem, int index) {
  268.     for (int i = index ; i < elementCount ; i++) {
  269.         if (elem.equals(elementData[i])) {
  270.         return i;
  271.         }
  272.     }
  273.     return -1;
  274.     }
  275.  
  276.     /**
  277.      * Returns the index of the last occurrence of the specified object in
  278.      * this vector.
  279.      *
  280.      * @param   elem   the desired component.
  281.      * @return  the index of the last occurrence of the specified object in
  282.      *          this vector; returns <code>-1</code> if the object is not found.
  283.      * @since   JDK1.0
  284.      */
  285.     public final int lastIndexOf(Object elem) {
  286.     return lastIndexOf(elem, elementCount-1);
  287.     }
  288.  
  289.     /**
  290.      * Searches backwards for the specified object, starting from the 
  291.      * specified index, and returns an index to it. 
  292.      *
  293.      * @param   elem    the desired component.
  294.      * @param   index   the index to start searching from.
  295.      * @return  the index of the last occurrence of the specified object in this
  296.      *          vector at position less than <code>index</code> in the vector;
  297.      *          <code>-1</code> if the object is not found.
  298.      * @since   JDK1.0
  299.      */
  300.     public final synchronized int lastIndexOf(Object elem, int index) {
  301.     for (int i = index ; i >= 0 ; i--) {
  302.         if (elem.equals(elementData[i])) {
  303.         return i;
  304.         }
  305.     }
  306.     return -1;
  307.     }
  308.  
  309.     /**
  310.      * Returns the component at the specified index.
  311.      *
  312.      * @param      index   an index into this vector.
  313.      * @return     the component at the specified index.
  314.      * @exception  ArrayIndexOutOfBoundsException  if an invalid index was
  315.      *               given.
  316.      * @since      JDK1.0
  317.      */
  318.     public final synchronized Object elementAt(int index) {
  319.     if (index >= elementCount) {
  320.         throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
  321.     }
  322.     /* Since try/catch is free, except when the exception is thrown,
  323.        put in this extra try/catch to catch negative indexes and
  324.        display a more informative error message.  This might not
  325.        be appropriate, especially if we have a decent debugging
  326.        environment - JP. */
  327.     try {
  328.         return elementData[index];
  329.     } catch (ArrayIndexOutOfBoundsException e) {
  330.         throw new ArrayIndexOutOfBoundsException(index + " < 0");
  331.     }
  332.     }
  333.  
  334.     /**
  335.      * Returns the first component of this vector.
  336.      *
  337.      * @return     the first component of this vector.
  338.      * @exception  NoSuchElementException  if this vector has no components.
  339.      * @since      JDK1.0
  340.      */
  341.     public final synchronized Object firstElement() {
  342.     if (elementCount == 0) {
  343.         throw new NoSuchElementException();
  344.     }
  345.     return elementData[0];
  346.     }
  347.  
  348.     /**
  349.      * Returns the last component of the vector.
  350.      *
  351.      * @return  the last component of the vector, i.e., the component at index
  352.      *          <code>size() - 1</code>.
  353.      * @exception  NoSuchElementException  if this vector is empty.
  354.      * @since   JDK1.0
  355.      */
  356.     public final synchronized Object lastElement() {
  357.     if (elementCount == 0) {
  358.         throw new NoSuchElementException();
  359.     }
  360.     return elementData[elementCount - 1];
  361.     }
  362.  
  363.     /**
  364.      * Sets the component at the specified <code>index</code> of this 
  365.      * vector to be the specified object. The previous component at that 
  366.      * position is discarded. 
  367.      * <p>
  368.      * The index must be a value greater than or equal to <code>0</code> 
  369.      * and less than the current size of the vector. 
  370.      *
  371.      * @param      obj     what the component is to be set to.
  372.      * @param      index   the specified index.
  373.      * @exception  ArrayIndexOutOfBoundsException  if the index was invalid.
  374.      * @see        java.util.Vector#size()
  375.      * @since      JDK1.0
  376.      */
  377.     public final synchronized void setElementAt(Object obj, int index) {
  378.     if (index >= elementCount) {
  379.         throw new ArrayIndexOutOfBoundsException(index + " >= " + 
  380.                              elementCount);
  381.     }
  382.     elementData[index] = obj;
  383.     }
  384.  
  385.     /**
  386.      * Deletes the component at the specified index. Each component in 
  387.      * this vector with an index greater or equal to the specified 
  388.      * <code>index</code> is shifted downward to have an index one 
  389.      * smaller than the value it had previously. 
  390.      * <p>
  391.      * The index must be a value greater than or equal to <code>0</code> 
  392.      * and less than the current size of the vector. 
  393.      *
  394.      * @param      index   the index of the object to remove.
  395.      * @exception  ArrayIndexOutOfBoundsException  if the index was invalid.
  396.      * @see        java.util.Vector#size()
  397.      * @since      JDK1.0
  398.      */
  399.     public final synchronized void removeElementAt(int index) {
  400.     if (index >= elementCount) {
  401.         throw new ArrayIndexOutOfBoundsException(index + " >= " + 
  402.                              elementCount);
  403.     }
  404.     else if (index < 0) {
  405.         throw new ArrayIndexOutOfBoundsException(index);
  406.     }
  407.     int j = elementCount - index - 1;
  408.     if (j > 0) {
  409.         System.arraycopy(elementData, index + 1, elementData, index, j);
  410.     }
  411.     elementCount--;
  412.     elementData[elementCount] = null; /* to let gc do its work */
  413.     }
  414.  
  415.     /**
  416.      * Inserts the specified object as a component in this vector at the 
  417.      * specified <code>index</code>. Each component in this vector with 
  418.      * an index greater or equal to the specified <code>index</code> is 
  419.      * shifted upward to have an index one greater than the value it had 
  420.      * previously. 
  421.      * <p>
  422.      * The index must be a value greater than or equal to <code>0</code> 
  423.      * and less than or equal to the current size of the vector. 
  424.      *
  425.      * @param      obj     the component to insert.
  426.      * @param      index   where to insert the new component.
  427.      * @exception  ArrayIndexOutOfBoundsException  if the index was invalid.
  428.      * @see        java.util.Vector#size()
  429.      * @since      JDK1.0
  430.      */
  431.     public final synchronized void insertElementAt(Object obj, int index) {
  432.     int newcount = elementCount + 1;
  433.     if (index >= newcount) {
  434.         throw new ArrayIndexOutOfBoundsException(index
  435.                              + " > " + elementCount);
  436.     }
  437.     if (newcount > elementData.length) {
  438.         ensureCapacityHelper(newcount);
  439.     }
  440.     System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
  441.     elementData[index] = obj;
  442.     elementCount++;
  443.     }
  444.  
  445.     /**
  446.      * Adds the specified component to the end of this vector, 
  447.      * increasing its size by one. The capacity of this vector is 
  448.      * increased if its size becomes greater than its capacity. 
  449.      *
  450.      * @param   obj   the component to be added.
  451.      * @since   JDK1.0
  452.      */
  453.     public final synchronized void addElement(Object obj) {
  454.     int newcount = elementCount + 1;
  455.     if (newcount > elementData.length) {
  456.         ensureCapacityHelper(newcount);
  457.     }
  458.     elementData[elementCount++] = obj;
  459.     }
  460.  
  461.     /**
  462.      * Removes the first occurrence of the argument from this vector. If 
  463.      * the object is found in this vector, each component in the vector 
  464.      * with an index greater or equal to the object's index is shifted 
  465.      * downward to have an index one smaller than the value it had previously.
  466.      *
  467.      * @param   obj   the component to be removed.
  468.      * @return  <code>true</code> if the argument was a component of this
  469.      *          vector; <code>false</code> otherwise.
  470.      * @since   JDK1.0
  471.      */
  472.     public final synchronized boolean removeElement(Object obj) {
  473.     int i = indexOf(obj);
  474.     if (i >= 0) {
  475.         removeElementAt(i);
  476.         return true;
  477.     }
  478.     return false;
  479.     }
  480.  
  481.     /**
  482.      * Removes all components from this vector and sets its size to zero.
  483.      *
  484.      * @since   JDK1.0
  485.      */
  486.     public final synchronized void removeAllElements() {
  487.     for (int i = 0; i < elementCount; i++) {
  488.         elementData[i] = null;
  489.     }
  490.     elementCount = 0;
  491.     }
  492.  
  493.     /**
  494.      * Returns a clone of this vector.
  495.      *
  496.      * @return  a clone of this vector.
  497.      * @since   JDK1.0
  498.      */
  499.     public synchronized Object clone() {
  500.     try { 
  501.         Vector v = (Vector)super.clone();
  502.         v.elementData = new Object[elementCount];
  503.         System.arraycopy(elementData, 0, v.elementData, 0, elementCount);
  504.         return v;
  505.     } catch (CloneNotSupportedException e) { 
  506.         // this shouldn't happen, since we are Cloneable
  507.         throw new InternalError();
  508.     }
  509.     }
  510.  
  511.     /**
  512.      * Returns a string representation of this vector. 
  513.      *
  514.      * @return  a string representation of this vector.
  515.      * @since   JDK1.0
  516.      */
  517.     public final synchronized String toString() {
  518.     int max = size() - 1;
  519.     StringBuffer buf = new StringBuffer();
  520.     Enumeration e = elements();
  521.     buf.append("[");
  522.  
  523.     for (int i = 0 ; i <= max ; i++) {
  524.         String s = e.nextElement().toString();
  525.         buf.append(s);
  526.         if (i < max) {
  527.         buf.append(", ");
  528.         }
  529.     }
  530.     buf.append("]");
  531.     return buf.toString();
  532.     }
  533. }
  534.  
  535. final
  536. class VectorEnumerator implements Enumeration {
  537.     Vector vector;
  538.     int count;
  539.  
  540.     VectorEnumerator(Vector v) {
  541.     vector = v;
  542.     count = 0;
  543.     }
  544.  
  545.     public boolean hasMoreElements() {
  546.     return count < vector.elementCount;
  547.     }
  548.  
  549.     public Object nextElement() {
  550.     synchronized (vector) {
  551.         if (count < vector.elementCount) {
  552.         return vector.elementData[count++];
  553.         }
  554.     }
  555.     throw new NoSuchElementException("VectorEnumerator");
  556.     }
  557. }
  558.